﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.CApAssignDataFromTCApp
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using DnProcessSimulateCommands.AssignDataFromTC;
using EngineeringInternalExtension;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Tecnomatix.Engineering;
using Tecnomatix.Engineering.Utilities;


namespace DnProcessSimulateCommands;

internal class CApAssignDataFromTCApp : IDisposable
{
  private static Task _searchTask;
  private static CancellationTokenSource _cancelTokenSource = (CancellationTokenSource) null;
  private CApTcIntegrationWrapper _tcIntegrationWrapper;
  private static string UID_PREFIX = "BOM::";

  public event Action<CApResultObjectsEventArgs> ObjectsReceived;

  public event Action<CApObjectsLoadedEventArgs> ObjectsLoaded;

  public CApAssignDataFromTCApp() => this._tcIntegrationWrapper = new CApTcIntegrationWrapper();

  public void StartSearch(
    string itemId,
    string itemRevisionName,
    IEnumerable<CUiSearchScope> targetScopes,
    IEnumerable<string> selectedProperties)
  {
    CApAssignDataFromTCApp._cancelTokenSource = new CancellationTokenSource();
    CApAssignDataFromTCApp._searchTask = Task.Factory.StartNew((Action) (() => this.StartSearchWork(itemId, itemRevisionName, targetScopes, selectedProperties)), CApAssignDataFromTCApp._cancelTokenSource.Token);
    CApAssignDataFromTCApp._searchTask.ContinueWith(new Action<Task>(this.HandleSearchException), TaskContinuationOptions.OnlyOnFaulted);
    CApAssignDataFromTCApp._searchTask.ContinueWith(new Action<Task>(this.HandleCancelSearch), TaskContinuationOptions.OnlyOnCanceled);
  }

  public void StopSearch() => CApAssignDataFromTCApp._cancelTokenSource.Cancel();

  public static TxPlanningTypeMetaData GetTypeMetaData(string planningType)
  {
    TxPlanningTypeMetaData typeMetaData = (TxPlanningTypeMetaData) null;
    if (TxApplication.ActiveDocument.PlatformGlobalServicesProvider is ITxTcGlobalServicesProvider servicesProvider && ((ITxPlatformGlobalServicesProvider) servicesProvider).IsDataLoaded())
      typeMetaData = ((ITxPlatformGlobalServicesProvider) servicesProvider).GetTypeMetaData(planningType);
    return typeMetaData;
  }

  public static CApSearchScopes GetSearchScopes()
  {
    List<CUiSearchScope> source1 = new List<CUiSearchScope>();
    List<CUiSearchScope> source2 = new List<CUiSearchScope>();
    foreach (Tuple<string, string, string, string, string, string> productScope in TxTcSessionInfoEx.ProductScopes)
      source1.Add(new CUiSearchScope(CApAssignDataFromTCApp.UID_PREFIX + productScope.Item1, productScope.Item2, productScope.Item3, productScope.Item4, productScope.Item5, false) ?? throw new SystemException(AssignDataFromTCResources.INFO_CANNOT_LOAD_SCOPES));
    foreach (Tuple<string, string, string, string, string, string> plantScope in TxTcSessionInfoEx.PlantScopes)
      source2.Add(new CUiSearchScope(CApAssignDataFromTCApp.UID_PREFIX + plantScope.Item1, plantScope.Item2, plantScope.Item3, plantScope.Item4, plantScope.Item5, true) ?? throw new SystemException(AssignDataFromTCResources.INFO_CANNOT_LOAD_SCOPES));
    return new CApSearchScopes(source1.OfType<CUiSearchScope>(), source2.OfType<CUiSearchScope>());
  }

  public void LoadObjects(
    bool loadForPreview,
    IEnumerable<CUiSearchResultObject> objectsForLoad,
    bool isConsumption)
  {
    TxTcImportResultEx importResult = (TxTcImportResultEx) null;
    try
    {
      TxApplicationEx.FireDocumentUpdateStarted();
      IEnumerable<TxTcImportObjectDataEx> objectsForImport = CApAssignDataFromTCApp.GetObjectsForImport(objectsForLoad);
      importResult = TxTcDataImporterEx.LoadObjects(loadForPreview, objectsForImport);
    }
    catch (Exception ex)
    {
      TxApplication.LogWriter.WriteExceptionLine(ex);
    }
    finally
    {
      TxApplicationEx.FireDocumentUpdateEnded();
      TxApplication.RefreshDisplay();
      if (this.ObjectsLoaded != null)
        this.ObjectsLoaded(new CApObjectsLoadedEventArgs(loadForPreview, importResult, isConsumption));
    }
  }

  public IDictionary<string, IDictionary<string, string>> LoadObjectsProperties(
    IEnumerable<string> uids,
    IEnumerable<string> propertiesList)
  {
    return this._tcIntegrationWrapper.GetObjectsProperties(uids, propertiesList);
  }

  private void StartSearchWork(
    string itemId,
    string itemRevisionName,
    IEnumerable<CUiSearchScope> targetScopes,
    IEnumerable<string> selectedProperties)
  {
    foreach (CUiSearchScope targetScope in targetScopes)
    {
      CancellationToken token = CApAssignDataFromTCApp._cancelTokenSource.Token;
      token.ThrowIfCancellationRequested();
      CApStructureSearchResultResponse searchResultResponse = this._tcIntegrationWrapper.StartSearch(targetScope.Uid, itemId, itemRevisionName, CApAssignDataFromTCApp.GetAllowedRevisionTypes(), selectedProperties);
      token = CApAssignDataFromTCApp._cancelTokenSource.Token;
      token.ThrowIfCancellationRequested();
      this.SendResultObjects(targetScope, searchResultResponse.Objects);
      while (!searchResultResponse.Finished)
      {
        token = CApAssignDataFromTCApp._cancelTokenSource.Token;
        token.ThrowIfCancellationRequested();
        searchResultResponse = this._tcIntegrationWrapper.NextSearch();
        token = CApAssignDataFromTCApp._cancelTokenSource.Token;
        token.ThrowIfCancellationRequested();
        this.SendResultObjects(targetScope, searchResultResponse.Objects);
      }
    }
    this.SendResultObjects((CUiSearchScope) null, (IEnumerable<TcSoaModelObjectData>) null, true);
  }

  private void SendResultObjects(
    CUiSearchScope sourceScope,
    IEnumerable<TcSoaModelObjectData> objects,
    bool isFinished = false,
    bool isInterrupted = false)
  {
    if (this.ObjectsReceived == null)
      return;
    this.ObjectsReceived.BeginInvoke(new CApResultObjectsEventArgs(sourceScope, objects, isFinished, isInterrupted), (AsyncCallback) null, (object) null);
  }

  private void HandleCancelSearch(Task t)
  {
    this._tcIntegrationWrapper.StopSearch();
    this.SendResultObjects((CUiSearchScope) null, (IEnumerable<TcSoaModelObjectData>) null, true, true);
  }

  private void HandleSearchException(Task t)
  {
    AggregateException aggregateException = t.Exception.Flatten();
    Hashtable hashtable = new Hashtable();
    foreach (Exception innerException in aggregateException.InnerExceptions)
    {
      if (innerException is COMException)
        hashtable.Add((object) AssignDataFromTCResources.ERROR_SERVICE_SEARCH, (object) "");
      else
        hashtable.Add((object) AssignDataFromTCResources.ERROR_GENERAL_ERROR, (object) "");
      TxApplication.LogWriter.WriteExceptionLine(innerException);
    }
    if (hashtable.Count > 0)
      TxErrorWindow.ShowDialog(AssignDataFromTCResources.CMD_NAME, AssignDataFromTCResources.PROBLEMS_DURING_SEARCH, hashtable, new Hashtable(), true);
    this.SendResultObjects((CUiSearchScope) null, (IEnumerable<TcSoaModelObjectData>) null, true, true);
  }

  private static IEnumerable<TxTcImportObjectDataEx> GetObjectsForImport(
    IEnumerable<CUiSearchResultObject> resultObjects)
  {
    List<TxTcImportObjectDataEx> objectsForImport = new List<TxTcImportObjectDataEx>();
    foreach (CUiSearchResultObject resultObject in resultObjects)
      objectsForImport.Add(new TxTcImportObjectDataEx(resultObject.CloneStableIdChain, resultObject.SourceScope.ScopeViewId, resultObject.Uid));
    return (IEnumerable<TxTcImportObjectDataEx>) objectsForImport;
  }

  public static IEnumerable<string> GetAllowedRevisionTypes()
  {
    List<string> allowedRevisionTypes = new List<string>();
    TxPlanningTypeMetaData typeMetaData1 = CApAssignDataFromTCApp.GetTypeMetaData(CApPropertiesManager.ITEM_REVISION_PLANNING_TYPE);
    TxPlanningTypeMetaData typeMetaData2 = CApAssignDataFromTCApp.GetTypeMetaData(CApPropertiesManager.ME_WORKAREA_REVISION_PLANNING_TYPE);
    if (typeMetaData1 != null && typeMetaData2 != null)
    {
      foreach (TxPlanningTypeMetaData allowedChildrenType in typeMetaData1.AllowedChildrenTypes)
      {
        if (!allowedRevisionTypes.Contains(allowedChildrenType.TypeName))
          allowedRevisionTypes.Add(allowedChildrenType.TypeName);
      }
      foreach (TxPlanningTypeMetaData allowedChildrenType in typeMetaData2.AllowedChildrenTypes)
      {
        if (!allowedRevisionTypes.Contains(allowedChildrenType.TypeName))
          allowedRevisionTypes.Add(allowedChildrenType.TypeName);
      }
    }
    return (IEnumerable<string>) allowedRevisionTypes;
  }

  public void Dispose() => this._tcIntegrationWrapper.Dispose();
}
